use crate::base::Coord;

pub use super::base::Cell;
pub use super::base::Color;
pub use super::base::Grid;
use raqote::*;

pub fn write_png(grid: &Grid, output_path: &str) {
    const CELL_SIZE: i32 = 20;

    let height = grid.height();
    let width = grid.width();

    let mut dt = DrawTarget::new((width + 2) * CELL_SIZE, (height + 2) * CELL_SIZE);

    dt.fill_rect(
        0.,
        0.,
        ((width + 2) * CELL_SIZE) as f32,
        ((height + 2) * CELL_SIZE) as f32,
        &Source::Solid(SolidSource::from_unpremultiplied_argb(255, 0, 0, 0)),
        &DrawOptions::new(),
    );
    
    dt.fill_rect(
        CELL_SIZE as f32,
        CELL_SIZE as f32,
        (width * CELL_SIZE) as f32,
        (height * CELL_SIZE) as f32,
        &Source::Solid(SolidSource::from_unpremultiplied_argb(255, 255, 255, 255)),
        &DrawOptions::new(),
    );

    for row in 0..height {
        for col in 0..width {
            let y = ((row + 1) * CELL_SIZE) as f32;
            let x = ((col + 1) * CELL_SIZE) as f32;

            let color = grid.cell(Coord::new(col, row)).unwrap().color();

            let mut pb = PathBuilder::new();
            pb.rect(x + 1., y + 1., CELL_SIZE as f32 - 2., CELL_SIZE as f32 - 2.);
            let path = pb.finish();
            dt.fill(&path, &color_to_source(&color), &DrawOptions::new());
        }
    }

    dt.write_png(output_path).unwrap();
}

fn color_to_source(color: &Color) -> Source {
    Source::Solid(SolidSource::from_unpremultiplied_argb(
        255, color.r, color.g, color.b,
    ))
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_write_png() {
        let mut gird = Grid::new(100, 100);
        gird.set_cell(Coord::new(10, 10), Cell::Routed(Color::white()));
        gird.set_cell(Coord::new(11, 10), Cell::Routed(Color::white()));
        gird.set_cell(Coord::new(10, 11), Cell::Routed(Color::white()));
        write_png(&gird, "./pic.png");
    }
}
